package hk.com.carfield.web.simple;

import hk.com.carfield.core.Config;
import hk.com.carfield.util.FileObject;
import hk.com.carfield.util.LogUtil;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.io.IOUtils;
import org.simpleframework.http.Part;
import org.simpleframework.http.session.Session;
import org.simpleframework.util.lease.LeaseException;

public class Request extends hk.com.carfield.web.Request {
	public static final hk.com.carfield.web.Request getRequest(
			final org.simpleframework.http.Request req, final Config config) {
		final Map<String, FileObject> fileObjectMap = new HashMap<String, FileObject>();
		try {
			final List<Part> list = req.getForm().getParts();
			for (int i = 0; i < list.size(); i++) {
				final Part part = list.get(i);
				if (part.isFile()) {
					LogUtil.log("It is a file: " + part.getFileName());
					fileObjectMap.put(part.getFileName(), new FileObject() {
						public void delete() {

						}

						public String getName() {
							return part.getFileName();
						}

						public void write(final File file) {
							try {
								LogUtil.log("write to: " + file);
								IOUtils.copy(part.getInputStream(),
										new FileOutputStream(file));
							} catch (final IOException e) {
								throw new RuntimeException(e);
							}
						}
					});
				}
			}
			return new Request(config, req, fileObjectMap);
		} catch (final Exception e) {
			throw new RuntimeException(e);
		}
	}

	private final Map<String, FileObject> fileObjectMap;

	private final org.simpleframework.http.Request request;

	@SuppressWarnings("rawtypes")
	private final Session session;

	public Request(final Config config,
			final org.simpleframework.http.Request req,
			final Map<String, FileObject> fileObjectMap) throws LeaseException {
		super(config.getAdminPassword());
		request = req;
		session = req.getSession();
		this.fileObjectMap = fileObjectMap;
	}

	@Override
	public String clientIP() {
		return request.getClientAddress().toString();
	}

	@Override
	public Collection<FileObject> getFileObject() {
		return fileObjectMap.values();
	}

	@Override
	public final String getParameter(final String name) {
		try {
			final String str = request.getParameter(name);
			if (str == null) {
				return "";
			} else {
				return str;
			}
		} catch (final IOException e) {
			throw new RuntimeException(e);
		}
	}

	@Override
	protected String getSessionValue(final String name) {
		return (String) session.get(name);
	}

	@Override
	public String host() {
		return request.getValue("host");
	}

	@SuppressWarnings("unchecked")
	@Override
	protected void setSessionValue(final String name, final String value) {
		session.put(name, value);
	}

	@Override
	public String toString() {
		final StringBuffer sb = new StringBuffer();
		try {
			sb.append("\n====super.toString():\n").append(super.toString());
			sb.append("\nPath:\t").append(request.getPath().getPath());
			sb.append("\nParameters:\t").append(request.getForm().entrySet());
			for (@SuppressWarnings("unchecked")
			final Iterator<String> iter = request.getAttributes().keySet()
					.iterator(); iter.hasNext();) {
				final String name = iter.next();
				sb.append(name).append(":\t")
						.append(request.getAttributes().get(name)).append("\n");
			}
		} catch (final IOException e) {
			throw new RuntimeException(e);
		}
		return sb.toString();
	}
}
